package com.vichat.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.vichat.common.cache.LocalCacher;
import com.vichat.common.cache.RedisHelper;
import com.vichat.common.constant.GlobalConstant;
import com.vichat.common.constant.I18nConstant;
import com.vichat.common.exception.ViChatException;
import com.vichat.common.signal.SignalCmdUtil;
import com.vichat.common.util.*;
import com.vichat.common.vo.Json;
import com.vichat.common.vo.PageFilter;
import com.vichat.user.cache.I18nMappingCache;
import com.vichat.user.entity.*;
import com.vichat.user.init.ApplicationCacheInit;
import com.vichat.user.service.IStaticDataService;
import com.vichat.user.service.IUserService;
import com.vichat.user.util.SessionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by ranjx on 2017/10/13.
 */
@Controller
@RequestMapping("/vc/")
public class RegisterController {
    protected static final Logger logger = LoggerFactory.getLogger(RegisterController.class);
    @Autowired
    HttpServletRequest request;
    @Autowired
    HttpServletResponse response;
    @Autowired
    private IUserService userService;
    @Autowired
    private IStaticDataService staticDataService;

    @Autowired
    private ApplicationCacheInit applicationCacheInit;

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormat.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true)); // true:允许输入空值，false:不能为空值
    }

    /**
     * 验证码
     *
     * @throws IOException
     */
    @RequestMapping("/captcha")
    @ResponseBody
    public void captcha() throws IOException {
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        // 生成随机字串
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        // 存入会话session
        SessionUtils.setSessionCaptcha(request, verifyCode);
        // 生成图片
        int w = 120, h = 32;
        VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);
    }

    @RequestMapping("/checkCaptchaCode")
    @ResponseBody
    public Json checkCaptchaCode(String code) {
        Json json = new Json();
        try {
            String verifyCode = SessionUtils.getSessionCaptcha(request);
            if (StringUtils.equalsIgnoreCase(verifyCode, code)) {
                json.setSuccess(true);
            }
        } catch (Exception e) {
            json.setMsg(e.getMessage());
            json.setCode(-9);
        }
        return json;
    }


    /**
     * 注册企业
     *
     * @param party
     * @param company
     * @param user
     * @return
     */
    @RequestMapping("/registerCompany")
    @ResponseBody
    public Json registerCompany(UserParty party, UserPartyCompany company, UserBasic user) {
        Json json = new Json();
        try {
            String password = user.getPassword();
            if (StringUtils.isEmpty(password)) {
                json.setMsg("密码不能为空");
            } else {
                party.setPhoneState(GlobalConstant.PHONE_MODEL_1);
                userService.registerPartyCompany(party, company, user);
                json.setMsg("注册成功");
                json.setSuccess(true);
            }
        } catch (ViChatException e) {
            e.printStackTrace();
            json.setI18nCode(e.getCode());
            json.setMsg(e.getMessage());
            json.setCode(-9);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
            json.setCode(-9);
        }
        return json;
    }


    @RequestMapping("/doLogin")
    @ResponseBody
    public Json doLogin(String account, String password, String code, String domain, Model model) throws IOException {
        Json json = new Json();
        String msg = "";
        HashMap result = new HashMap();
        try {
            String verifyCode = SessionUtils.getSessionCaptcha(request);

            if (GlobalConstant.IS_SUPPORT_CAPTCHA &&
                    !StringUtils.equalsIgnoreCase(verifyCode, code)) {
                //验证码输入错误
                String errorMsg = I18NUtil.getMessage("RegisterController.doLogin.error_verifyCode", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_verifyCode, errorMsg);
            } else {
                UserBasic user = userService.getUserBasicByTerminal(account);
                if (user == null || user.getState() == 0) {
                    //登录信息有误
                    String errorMsg = I18NUtil.getMessage("RegisterController.doLogin.error_loginMsgError", null, Locale.getDefault());
                    throw new ViChatException(I18nConstant.error_loginMsgError, errorMsg);
                }
                if (user.getUserType() == GlobalConstant.USER_TYPE_4) {
                    //帐号已过期
                    if (user.getExpiredDate().before(new Date())) {
                        String errorMsg = I18NUtil.getMessage("RegisterController.doLogin.error_accountExpired", null, Locale.getDefault());
                        model.addAttribute("message", errorMsg);
                        throw new ViChatException(I18nConstant.error_accountExpired, errorMsg);
                    }
                    //非有效账号不能登录
                    if (user.getState().longValue() != 1) {
                        String errorMsg = I18NUtil.getMessage("RegisterController.noAuth.error_accountNoAuth", null, Locale.getDefault());
                        throw new ViChatException(I18nConstant.error_noAuth, errorMsg);
                    }
                }
                if (user.getUserType() == GlobalConstant.USER_TYPE_3) {
                    String errorMsg = I18NUtil.getMessage("RegisterController.noAuth.error_accountNoAuth", null, Locale.getDefault());
                    throw new ViChatException(I18nConstant.error_noAuth, errorMsg);
                }
                password = Md5Util.Md5Encode(password, null);
                password = Md5Util.Md5Encode(password, null);
                if (StringUtils.equals(user.getPassword(), password)) {

                    String jwtToken = JwtUtil.generateToken(Configure.getString("signing.key"), String.valueOf(user.uid));
                    RedisHelper.set("LOGIN_TOKEN:" + user.uid, jwtToken);// 一小时超时
                    result.put("access_token", jwtToken);
                    json.setObj(result);
                    json.setSuccess(true);

                } else {
                    //密码错误
                    String errorMsg = I18NUtil.getMessage("RegisterController.doLogin.error_pwdError", null, Locale.getDefault());
                    throw new ViChatException(I18nConstant.error_pwdError, errorMsg);
                }

            }
        } catch (ViChatException e) {
            e.printStackTrace();
            msg = e.getMessage();
            model.addAttribute("message", msg);
            model.addAttribute("i18nCode", e.getCode());
            json.setI18nCode(e.getCode());
            json.setCode(-9);
        } catch (Exception e) {
            e.printStackTrace();
            msg = e.getMessage();
            model.addAttribute("message", msg);
            json.setCode(-9);
        } finally {
            json.setMsg(msg);
            return json;
        }
    }

    @RequestMapping("/doLoginByPc")
    @ResponseBody
    public Json doLoginByPc(String account, Long uid, String password, String url, int times) throws IOException {
        Json json = new Json();
        try {
            HashMap result = new HashMap();
            UserBasic user = null;
            String token = null;
            if (StringUtils.isNotBlank(account)) {
                user = userService.getUserBasicByTerminal(account);
            } else if (NumberUtils.isNotNullOrZero(uid)) {
                user = userService.getUserBasicByUid(uid);
            }
            if (user == null) {
                //throw new Exception("登录信息有误");
                String errorMsg = I18NUtil.getMessage("RegisterController.doLogin.error_loginMsgError", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_loginMsgError, errorMsg);
            }
            //只有调度员才能登陆PC
            if (user.getUserType() == GlobalConstant.USER_TYPE_4) {
                //帐号已过期
                if (user.getExpiredDate().before(new Date())) {
                    String errorMsg = I18NUtil.getMessage("RegisterController.doLogin.error_accountExpired", null, Locale.getDefault());
                    throw new ViChatException(I18nConstant.error_accountExpired, errorMsg);
                }
                //非有效账号不能登录
                if (user.getState().longValue() != 1) {
                    String errorMsg = I18NUtil.getMessage("RegisterController.noAuth.error_accountNoAuth", null, Locale.getDefault());
                    throw new ViChatException(I18nConstant.error_noAuth, errorMsg);
                }
            }else {
                String errorMsg = I18NUtil.getMessage("RegisterController.noAuth.error_accountNoAuth", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_noAuth, errorMsg);
            }

            password = getEncodePwd(times, password);
            if (StringUtils.equals(user.getPassword(), password)) {
                token = RedisHelper.get("LOGIN_TOKEN:" + user.uid);
                if (!StringUtils.isNotBlank(token)) {
                    token = JwtUtil.generateToken(Configure.getString("signing.key"), String.valueOf(user.uid));
                    RedisHelper.set("LOGIN_TOKEN:" + user.uid, token, 60 * 1000 * 60 * 24);// 24小时超时
                }


            } else {
//                throw new Exception("密码错误");
                String errorMsg = I18NUtil.getMessage("RegisterController.doLogin.error_pwdError", null, Locale.getDefault());
                throw new ViChatException(I18nConstant.error_pwdError, errorMsg);
            }
            if (StringUtils.isNotBlank(url) && StringUtils.isNotBlank(token)) {
                if (StringUtils.isNotBlank(url) && "main".equalsIgnoreCase(url)) {
                    response.sendRedirect(getUrl()+"/transfer.html?access_token=" + token);
                } else {
                    response.sendRedirect(getUrl()+"/transfer.html?url=" + url + "&access_token=" + token);
                }
            }

            return json;
        } catch (ViChatException e) {
            e.printStackTrace();
            if (StringUtils.isNotBlank(url)) {
                response.sendRedirect("/vc/noAuth");
            } else {
                json.setI18nCode(e.getCode());
                json.setMsg(e.getMessage());
            }
            return json;
        } catch (Exception e) {
            e.printStackTrace();
            if (StringUtils.isNotBlank(url)) {
                response.sendRedirect("/vc/noAuth");
            } else {
                json.setMsg(e.getMessage());
            }
            return json;
        }
    }

    private String getUrl(){
        String serverName = request.getServerName();
        int port = request.getServerPort();
        StringBuilder sbd = new StringBuilder();
        // 强制使用https
        sbd.append("http://").append(serverName);
        if(port != 80 ) {
            sbd.append(":").append(port).append("/");
        }
        return sbd.toString();
    }


    private String getEncodePwd(int times, String password) {
        if (times == 1) {
            password = Md5Util.Md5Encode(password, null);
            return password;
        } else if (times == 2) {
            password = Md5Util.Md5Encode(password, null);
            password = Md5Util.Md5Encode(password, null);
            return password;
        }
        return password;
    }

    @RequestMapping("/noAuth")
    @ResponseBody
    public Json noAuth() throws IOException {
        Json json = new Json();
        json.setCode(-1);
//        json.setMsg("您没有授权访问该页面或接口");
        String msg = I18NUtil.getMessage("RegisterController.noAuth.error_accountNoAuth", null, Locale.getDefault());
        json.setI18nCode(I18nConstant.error_noAuth);
        json.setMsg(msg);
        return json;
    }

    @RequestMapping("/platform")
    @ResponseBody
    public Json platform() throws IOException {
        Json json = new Json();
        try {
            SysStaticData platformLongName = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "PLATFORM_NAME_LONG");
            SysStaticData platformShortName = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "PLATFORM_NAME_SHORT");

            SysStaticData gpsType = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "GPS_TYPE");

            SysStaticData supportAdminLoginApp = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "SUPPORT_ADMIN_LOGIN_APP");


            HashMap map = new HashMap();
            if (platformLongName != null) {
                map.put("platformNameLong", platformLongName.getCodeName());
            }
            if (platformShortName != null) {
                map.put("platformNameShort", platformShortName.getCodeName());
            }
            if (gpsType != null) {
                map.put("gpsType", gpsType.getCodeName());
            }
            if (supportAdminLoginApp != null) {
                map.put("supportAdminLoginApp", supportAdminLoginApp.getCodeName());
            }

            json.setObj(map);
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setCode(-9);
        } finally {
            return json;
        }
    }


    @RequestMapping("/refreshCache")
    @ResponseBody
    public Json refreshCache() throws IOException {
        Json json = new Json();
        try {
            ApplicationContext ctx = applicationCacheInit.getApplicationContext();
            LocalCacher.init(ctx);
            IStaticDataService staticDataService = (IStaticDataService) ctx.getBean("staticDataService", IStaticDataService.class);

            SysStaticData maxTerminalAuthNumber = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "MAX_TERMINAL_AUTH_NUMBER");
            if (maxTerminalAuthNumber != null) {
                GlobalConstant.MAX_TERMINAL_AUTH_NUMBER = Long.parseLong(maxTerminalAuthNumber.getCodeName());
            }
            SysStaticData maxDispatcherAuthNumber = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "MAX_DISPATCHER_AUTH_NUMBER");
            if (maxDispatcherAuthNumber != null) {
                GlobalConstant.MAX_DISPATCHER_AUTH_NUMBER = Long.parseLong(maxDispatcherAuthNumber.getCodeName());
            }
            SysStaticData usableFileSuffix = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "USABLE_FILE_SUFFIX");
            if (usableFileSuffix != null) {
                String[] usableFileSuffixs = String.valueOf(usableFileSuffix.getCodeName()).split("\\|");
                GlobalConstant.USABLE_FILE_SUFFIX_LIST = Arrays.asList(usableFileSuffixs);
            }
            SysStaticData supportAdminLoginApp = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "SUPPORT_ADMIN_LOGIN_APP");
            if (supportAdminLoginApp != null) {
                GlobalConstant.SUPPORT_ADMIN_LOGIN_APP = Boolean.parseBoolean(supportAdminLoginApp.getCodeName());
            }
            SysStaticData gpsType = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "GPS_TYPE");
            if (gpsType != null) {
                GlobalConstant.GPS_TYPE = gpsType.getCodeName();
            }
            SysStaticData sysLanguage = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "SYS_LANGUAGE");
            if (sysLanguage != null) {
                String language = sysLanguage.getCodeName();
                if(language.equals("China")){
                    GlobalConstant.SYS_LANGUAGE = Locale.CHINA;
                }else {
                    GlobalConstant.SYS_LANGUAGE = Locale.ENGLISH;
                }
            }
            SysStaticData checkDispatcherSn = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "CHECK_DISPATCHER_SN");
            if (checkDispatcherSn != null) {
                GlobalConstant.CHECK_DISPATCHER_SN = Boolean.parseBoolean(checkDispatcherSn.getCodeName());
            }
            SysStaticData checkTerminalSn = staticDataService.getStaticData(GlobalConstant.SYSTEM_PARAM, "CHECK_TERMINAL_SN");
            if (checkTerminalSn != null) {
                GlobalConstant.CHECK_TERMINAL_SN = Boolean.parseBoolean(checkTerminalSn.getCodeName());
            }

            //国际化内存刷新
            LocalCacher.refresh(I18nMappingCache.cacheId());

            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setCode(-9);
        } finally {
            return json;
        }
    }


//    @RequestMapping("/serviceDefine")
//    @ResponseBody
//    public Json serviceDefine() throws IOException {
//        Json json = new Json();
//        try {
//            List<ServiceDefineVO> serviceDefines = staticDataService.getServiceDefine();
//            for (ServiceDefineVO service : serviceDefines) {
//                getWebInstance().delKey(RedisKey.Service.SERVICE_CFG + ":" + service.srvType);
//            }
//            for (ServiceDefineVO service : serviceDefines) {
//                getWebInstance().sadd(RedisKey.Service.SERVICE_CFG, service.srvType, 0, JSON.toJSONString(service));
//            }
//            json.setSuccess(true);
//        } catch (Exception e) {
//            e.printStackTrace();
//        } finally {
//            return json;
//        }
//    }


    @RequestMapping("/send")
    @ResponseBody
    public Json send(long uid, String msg, String msgType) throws IOException {
        Json json = new Json();
        try {
            SignalCmdUtil.sendMsgByUMsgId(uid, 10000l, uid, msg, msgType, System.currentTimeMillis());
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setCode(-9);
        } finally {
            return json;
        }
    }


    @RequestMapping("/monitor")
    @ResponseBody
    public String monitor() throws IOException {
        return "ok";
    }

    /**
     * 加载用户->redis
     *
     * @return
     */
    @RequestMapping("/redis")
    @ResponseBody
    public Json loadUser2Redis() {
        Json json = new Json();
        try {
            {
                UserBasic queryBean = new UserBasic();
                queryBean.setDisplayState(99L);
                PageFilter pf = PageFilter.getMaxPageFilter();
                PageFilter.getMaxPageFilter();
                List<UserBasic> users = userService.queryUserBasics(queryBean, pf, false);
                HashMap<Long, String> orgMap = new HashMap<Long, String>();
                logger.error(users.size() + "");
                if (!users.isEmpty()) {
                    for (UserBasic user : users) {
                        RedisHelper.setUser(user.getUid(), JSONObject.toJSONString(user));
                        long orgId = user.getOrgId();
                        if (!orgMap.containsKey(orgId)) {
                            String orgName = RedisHelper.getOrg(orgId);
                            orgMap.put(orgId, orgName);
                        }
                        user.setOrgName(orgMap.get(orgId));

                    }
                }
            }
            {
                UserParty queryBean = new UserParty();
                List<UserParty> edposPartyList = userService.getUserPartys();
                if (!edposPartyList.isEmpty()) {
                    for (UserParty edposParty : edposPartyList) {
                        RedisHelper.setParty(edposParty.getPartyId(), JSONObject.toJSONString(edposParty));
                    }
                }
            }
            {
                UserOrg queryBean = new UserOrg();
                PageFilter pf = PageFilter.getMaxPageFilter();
                PageFilter.getMaxPageFilter();
                List<UserOrg> edposOrgs = userService.queryUserOrgs(queryBean, pf);
                if (!edposOrgs.isEmpty()) {
                    for (UserOrg val : edposOrgs) {
                        RedisHelper.setOrg(val.getOrgId(), JSONObject.toJSONString(val));
                    }
                }
            }
            json.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            json.setMsg(e.getMessage());
        }
        return json;
    }
}
